      SUBROUTINE TAVISPAK(KREQMT,ELEMSIN,UTARG,ANGREQ,
     *       KFLAGOUT,ANG1,ANG2,LUERR,IERR)
      IMPLICIT REAL*8 (A-H,O-Z)
C
C THIS ROUTINE COMPUTES THE ANGLES = TRUE ANOMALY PLUS ARG-OF-PERIGEE
C BETWEEN WHICH A CELESTIAL POINT SOURCE TARGET(EX, A STAR, PLANET,
C ...) IS AVAILABLE FOR OBSERVATION FROM AN EARTH-ORBITING SPACECRAFT.
C
C >>> AVAILABLE MEANS THAT THE LINE OF SIGHT TO THE TARGET SATISFIES
C     THE APPROPRIATE CONDITION --
C
C      KREQMT = 1.  EARTH HORIZON AVOIDANCE. LINE OF SIGHT TO THE TARGET
C                   IS EQ/GT A SPECIFIED ANGLE ABOVE THE HORIZON.
C
C      KREQMT = 2.  VELOCITY VECTOR AVOIDANCE. LINE OF SIGHT TO THE
C                   TARGET IS EQ/GT A SPECIFIED ANGLE FROM THE VEL VEC.
C                   TARGET OCCULATION IS NOT CONSIDERED HERE.
C
C      KREQMT = 3.  ZENITH ANGLE RANGE. LINE OF SIGHT TO THE TARGET IS
C                   LT/EQ A SPECIFIED ANGLE FROM THE INSTANTANEOUS
C                   ZENITH DIRECTION. TARGET OCCULATION IS NOT
C                   CONSIDERED HERE.
C
C
C VARIABLE DIM TYPE I/O DESCRIPTION
C -------- --- ---- --- -----------
C
C
C KREQMT    1   I*4  I  AS DESCRIBED IN THE COMMENTS ABOVE. IF NOT
C                       1, 2, OR 3, AN ERROR CONDITION.
C
C ELEMSIN   5   R*8  I  THE KEPLERIAN ELEMENTS OF THE SPACECRAFT ORBIT.
C                       ORDER IS SMA, ECC, INCL, NODE, ARGP.
C                       IN KILOMETERS AND RADIANS.
C
C                       THE COORDINATE SYSTEM MAY BE ANY GEOCENTRIC ONE
C                       THAT IS CONVENIENT.
C
C                       ECCENTRICITY MAY BE ZERO.  IF SO, PERIGEE HAS NO
C                       PHYSICALLY UNIQUE LOCATION AND ZERO TRUE ANOMALY
C                       IS DEFINED TO OCCUR ELEMSIN(5) RADIANS AFTER THE
C                       S/C CROSSES THE ASCENDING NODE.
C
C UTARG     3   R*8  I  UNIT VECTOR OF THE TARGET. THE COORDINATE SYSTEM
C                       IS THE SAME AS THAT USED FOR ELEMSIN ABOVE. NO
C                       ERROR CHECK IS DONE TO VERIFY VECTOR IS UNIT.
C
C ANGREQ    1   R*8  I  FOR KREQMT=1,
C
C                         THE HORIZON AVOIDANCE ANGLE. IF THE TARGET
C                         DIRECTION LIES MORE THAN ANGREQ RADIANS ABOVE
C                         THE CURRENT HORIZON, THEN IT IS CONSIDERED
C                         AVAILABLE.  OTHERWISE, NOT AVAILABLE.
C                         IN RADIANS.
C
C                         (ANGREQ + SOLID EARTH ANGLE AT PERIGEE) MUST
C                         BE IN THE 0 TO PI RANGE, INCLUDING 0 AND
C                         PI.
C
C                       FOR KREQMT=2,
C
C                         THE VELOCITY VECTOR AVOIDANCE ANGLE. IF THE
C                         TARGET DIRECTION LIES MORE THAN ANGREQ RADIANS
C                         FROM THE VELOCITY VECTOR DIRECTION, THEN IT IS
C                         CONSIDERED AVAILABLE. OTHERWISE, NOT
C                         AVAILABLE. IN RADIANS.
C
C                         ANGREQ MUST BE IN THE 0 TO PI RANGE, INCLUDING
C                         0 AND PI.
C
C                       FOR KREQMT=3,
C                         THE ZENITH VECTOR SEPARATION ANGLE. IF THE
C                         TARGET DIRECTION LIES LESS THAN ANGREQ RADIANS
C                         FROM THE CURRENT ZENITH DIRECTION, THEN IT IS
C                         CONSIDERED AVAILABLE. OTHERWISE, NOT
C                         AVAILABLE. IN RADIANS.
C
C                         ANGREQ MUST BE IN THE 0 TO PI RANGE, INCLUDING
C                         0 AND PI.
C
C KFLAGOUT  1   I*4  O  FLAG INDICATING THE AVAILABILITY STATUS OF THE
C                       TARGET WHEN THE SPECIFIED REQUIREMENT IS
C                       APPLIED.
C
C                       = -1, TARGET NEVER AVAILABLE.
C                       =  0, TARGET SOMETIMES AVAILIBLE, SOMETIMES NOT.
C                       =  1, TARGET ALWAYS AVAILABLE.
C                       = 9999. ACCOMPANIES ERROR CONDITION.
C
C ANG1      1   R*8  O  THE SUM OF THE ARGUMENT OF PERIGEE AND THE
C                       TRUE ANOMALY AT WHICH THE TARGET BECOMES
C                       AVAILABLE.
C
C                       THIS IS THE ANGLE IN THE ORBIT PLANE, VERTEX AT
C                       EARTH CENTER, BETWEEN THE ASCENDING NODE AND
C                       THE PLACE WHERE AVAILABILITY BEGINS.
C
C                       IN RADIANS, IN RANGE ZERO TO TWOPI.
C
C ANG2      1   R*8  O  SIMILAR TO ANG1, BUT FOR THE PLACE WHERE
C                       AVAILABLITY CEASES.  IN RADIANS, IN RANGE ZERO
C                       TO TWOPI.
C
C                       ANG2 MAY BE SMALLER THAN ANG1.
C
C                       IF THE TARGET IS ALWAYS AVAILABLE, THEN
C                       ANG1 = 0.D0 AND ANG2 = TWOPI
C
C                       IF THE TARGET IS NEVER AVAILABLE, THEN
C                       ANG1 = 0.D0 AND ANG2 = 0.D0
C
C                       ON AN ERROR RETURN, ANG1 = ANG2 = 999.D0/DEGRAD
C
C LUERR     1   I*4  I  FORTRAN UNIT NUMBER FOR ERROR MESSAGES.
C                       IF ZERO OR NEGATIVE, NO MESSAGES WILL BE GIVEN.
C
C IERR      1   I*4  O  ERROR RETURN FLAG.
C                        = 0, NO ERRORS.
C                        = 1, BAD KREQMT VALUE INPUT
C                        = 2, BAD ELEMS(1) OR ELEMS(2)
C                        = 3, ALGORITHM ERROR IN TAVISPAK99
C                        = 4, ALGORITHM DID NOT CONVERGE
C                        = 5, (KREQMT=1) ANGREQ VALUE IS INCONSISTENT
C                             WITH REARTH AND ELEMS. SEE ERROR CHECK IN
C                             TAVISPAK51.
C                        = 6, (KREQMT=1) PERIGEE RADIUS IS BELOW THE
C                             EARTH SURFACE.
C                        = 7, (KREQMT=2 AND 3) ANGREQ IS OUTSIZE OF THE
C                             0 TO PI RANGE.
C                        = 8, ALGORITHM ERROR IN TAVISPAK3B
C
C                        IF AN ERROR IS SENSED, ANG1=ANG2=0.D0 IS
C                        RETURNED.
C
C***********************************************************************
C
C CODED BY C PETRUZZO, GSFC/742, 1/86.
C    MODIFIED....  CJP. 10/86.  COMMENT ADDED IN ELEMSIN DESCRIPTION.
C
C***********************************************************************
C
C THE UNDERLYING ALGORITHMS WERE DERIVED BY H.P. SWARTWOOD(GSFC/742) AND
C WERE DOCUMENTED IN MEMORANDUMS TO FILES IN OCTOBER AND NOVEMBER, 1985.
C
C
      REAL*8 UTARG(3),ORBDATA(20)
      REAL*8 ELEMSIN(5),ELEMOLD(5)/5*1.D10/,ELEMS(5),ORBNORM(3)
      LOGICAL NEWSTATE
      REAL*8 PI     / 3.141592653589793D0 /
      REAL*8 TWOPI  / 6.283185307179586D0 /
      REAL*8 DEGRAD / 57.29577951308232D0 /
      REAL*8 PITESTMIN/0.D0/
C
      IBUG = 0
      LUBUG = 19
C
      IF(IBUG.NE.0) WRITE(LUBUG,7701)
     *    KREQMT,ELEMSIN(1),ELEMSIN(2),(ELEMSIN(I)*DEGRAD,I=3,6),
     *    UTARG,ANGREQ*DEGRAD
 7701 FORMAT(/,' TAVISPAK DEBUG. ENTRY VALUES ARE    KREQMT=',I4/,
     *  '    ELEMSIN=',2(T15,3G16.8/),
     *  '    UTARG=',3G16.8/,
     *  '    ANGREQ=',G16.8)
C
C ****************
C *  INITIALIZE  *
C ****************
C
      IERR = 0
C
      DO I=1,5
        ELEMS(I) = ELEMSIN(I)
        END DO
      IF(ELEMSIN(2).EQ.0.D0) ELEMS(5) = 0.D0   ! ELIMINATES AMBIGUITY
      IF(PITESTMIN.EQ.0.D0) THEN
        PITESTMIN =  PI - 1.D-4/DEGRAD
        PITESTMAX =  PI + 1.D-4/DEGRAD
        ZEROTEST =        1.D-4/DEGRAD
        END IF
C
C
C ******************
C *  ERROR CHECKS  *
C ******************
C
      CALL TAVISPAK1(KREQMT,ELEMS,ANGREQ,LUERR,IERR)
      IF(IERR.NE.0) GO TO 9999
C
C
C *********************************************************
C *  CHECK FOR ANGREQ VALUES THAT DO NOT NEED ALGORITHMS  * SAVES TIME
C *********************************************************
C
C FOR VELOCITY VECTOR AVOIDANCE
C
      IF(KREQMT.EQ.2) THEN
        IF(ANGREQ.LE.ZEROTEST) THEN
C        IE, TARGET IS GT/EQ ZERO RADIANS FROM VELOCITY VECTOR
          KVISFLAG = 1   ! ALWAYS
          GO TO 9999
          END IF
        IF(ANGREQ.GE.PITESTMIN) THEN
C        IE, TARGET IS PI RADIANS FROM VELOCITY VECTOR
          KVISFLAG = -1  !NEVER. ACTUALLY, ONLY INSTANTANEOUSLY POSSIBLE
          GO TO 9999
          END IF
        END IF
C
C FOR ZENITH MAX SEPARATION REQUIREMENT
C
      IF(KREQMT.EQ.3) THEN
        IF(ANGREQ.LE.ZEROTEST) THEN
C        IE, TARGET IS WITHIN ZERO RADIANS OF ZENITH
          KVISFLAG = -1  !NEVER. ACTUALLY, ONLY INSTANTANEOUSLY POSSIBLE
          GO TO 9999
          END IF
        IF(ANGREQ.GE.PITESTMIN) THEN
C        IE, TARGET IS WITHIN PI RADIANS OF ZENITH
          KVISFLAG = 1   ! ALWAYS
          GO TO 9999
          END IF
        END IF
C
C ***********************************************
C * SET DATA RELATED TO THE ORBITAL PARAMETERS  *
C ***********************************************
C
C IF THE STATE IS DIFFERENT THAN ON THE PREVIOUS CALL, COMPUTE NEW
C VALUES FOR THE ORBDATA ARRAY.
C
      NEWSTATE = .FALSE.
      DO I=1,5
        NEWSTATE = NEWSTATE .OR. ELEMOLD(I).NE.ELEMS(I)
        END DO
      IF(NEWSTATE) THEN
        CALL TAVISPAK2(ELEMS,ORBDATA)
        IF(IBUG.NE.0) THEN
          ORBNORM(1) = ORBDATA(18)
          ORBNORM(2) = ORBDATA(19)
          ORBNORM(3) = ORBDATA(20)
          CALL XYZSPH(-1,RANORM,DECNORM,DUM,ORBNORM,1.D0)
          WRITE(LUBUG,7702) RANORM*DEGRAD,DECNORM*DEGRAD,ORBDATA
 7702     FORMAT(/,' TAVISPAK DEBUG 7702.   RANORM,DECNORM=',2G13.5/,
     *             '   ORBDATA='/,(T12,4G16.8))
          END IF
        END IF
C
C
C **************
C *  SOLVE IT  *
C **************
C
      CALL TAVISPAK3(KREQMT,ELEMS,UTARG,ANGREQ,
     *       KVISFLAG,EABEGIN,EACEASE,ORBDATA,LUERR,IERR)
      IF(IERR.NE.0) GO TO 9999
C
C
C *************
C *  WRAP UP  *
C *************
C
 9999 CONTINUE
C
      IF(IERR.EQ.0) THEN
C
       IF(KVISFLAG.EQ.0) THEN
C        SET THE TRUE ANOMALY PLUS ARGUMENT OF PERIGEE
          KFLAGOUT = 0
          ANG1 = EQVANG(ELEMS(5)+ANOMLY2(1,EABEGIN,ELEMS(2),LUERR,IER1))
          IF(IER1.NE.0) THEN
C          ELEMS(2) WAS TESTED IN TAVISPAK1 AND WAS OK.  NOT OK NOW.
            STOP ' TAVISPAK. CODING ERROR. STOPPED.'
            END IF
          ANG2 = EQVANG(ELEMS(5)+ANOMLY2(1,EACEASE,ELEMS(2),LUERR,IER2))
        ELSE
          IF(KVISFLAG.EQ.-1) THEN
C          TARGET IS NEVER AVAILABLE.
            KFLAGOUT = -1
            ANG1 = 0.D0
            ANG2 = 0.D0
            END IF
          IF(KVISFLAG.EQ.+1) THEN
C          TARGET IS ALWAYS AVAILABLE.
            KFLAGOUT = 1
            ANG1 = 0.D0
            ANG2 = TWOPI
            END IF
          END IF
C      SAVE INFO FOR USE ON NEXT CALL.
        DO I=1,5
          ELEMOLD(I) = ELEMS(I)
          END DO
        END IF
C
      IF(IERR.NE.0) THEN
C      ERROR CONDITION.  SET ANG1 AND ANG2 AS STATED IN THE PROLOGUE.
C      THE ELEMOLD(1) VALUE MAKES THE NEXT CALL INITIALIZE PROPERLY.
        ELEMOLD(1) = -1.D10
        KFLAGOUT = 9999
        ANG1 = 999.D0/DEGRAD
        ANG2 = ANG1
        CALL TAVISPAK4(KREQMT,ELEMS,LUERR,IERR)
        END IF
C
      IF(IBUG.NE.0) WRITE(LUBUG,8605) IERR,ANG1*DEGRAD,ANG2*DEGRAD
 8605 FORMAT(' TAVISPAK DEBUG. EXIT VALUES: IERR=',I2,'  ANG1,ANG2=',
     *           2G13.5/)
C
      RETURN
      END
